package cn.javaxc.process.service;

import cn.javaxc.mvcwork.util.helper.IBaseDAO;
import cn.javaxc.process.model.*;
import cn.javaxc.model.base.*;
import cn.javaxc.mvcwork.modules.login.*;
import cn.javaxc.mvcwork.framework.actions.*;
import cn.javaxc.mvcwork.controller.web.PagedListInfo;
import javax.servlet.http.*;
import cn.javaxc.mvcwork.util.common.MSecurityUtils;

import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.*;

/**
 * 请假业务Service业务层处理
 *
 * @author Xianlu Tech
 * @date 2019-10-11
 */
@Service
@Transactional
public class BizLeaveServiceImpl {
    @Autowired
    private BizLeaveMapper bizLeaveMapper;

    @Autowired
    private IdentityService identityService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

//    @Autowired
//    private SysUserMapper userMapper;

    @Autowired
    private BizTodoItemServiceImpl bizTodoItemService;

	@Autowired
	protected IBaseDAO userMapper;
    /**
     * 查询请假业务
     *
     * @param id 请假业务ID
     * @return 请假业务
     */
    
    public BizLeaveVo selectBizLeaveById(Long id) {
        BizLeaveVo leave = bizLeaveMapper.selectBizLeaveById(id);
        SQLList<SQLMap> sysUser = userMapper.getuser(leave.getApplyUser());
        if (sysUser.size()>0) {
            leave.setApplyUserName(sysUser.get(0).getString("contact_name"));
        }
        return leave;
    }



    /**
     * 新增请假业务
     *
     * @param bizLeave 请假业务
     * @return 结果
     */
    
    public int insertBizLeave(BizLeaveVo bizLeave) {
        bizLeave.setCreateBy(getUser().getUsername());
        bizLeave.setCreateTime(new Date());
        return bizLeaveMapper.insertBizLeave(bizLeave);
    }

    /**
     * 修改请假业务
     *
     * @param bizLeave 请假业务
     * @return 结果
     */
    
    public int updateBizLeave(BizLeaveVo bizLeave) {
        bizLeave.setUpdateTime(new Date());
        return bizLeaveMapper.updateBizLeave(bizLeave);
    }

    /**
     * 删除请假业务对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    
    public int deleteBizLeaveByIds(String ids) {
        return bizLeaveMapper.deleteBizLeaveByIds(ids.split(","));
    }

    /**
     * 删除请假业务信息
     *
     * @param id 请假业务ID
     * @return 结果
     */
    
    public int deleteBizLeaveById(Long id) {
        return bizLeaveMapper.deleteBizLeaveById(id);
    }

    /**
     * 启动流程
     * @param entity
     * @param applyUserId
     * @return
     */
    
    public ProcessInstance submitApply(BizLeaveVo entity, String applyUserId) {
        entity.setApplyUser(applyUserId);
        entity.setApplyTime(new Date());
        entity.setUpdateBy(applyUserId);
        bizLeaveMapper.updateBizLeave(entity);
        String businessKey = entity.getId().toString(); // 实体类 ID，作为流程的业务 key

        // 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
        identityService.setAuthenticatedUserId(applyUserId);

        ProcessInstance processInstance = runtimeService // 启动流程时设置业务 key
                .startProcessInstanceByKey("leave", businessKey);
        String processInstanceId = processInstance.getId();
        entity.setInstanceId(processInstanceId); // 建立双向关系
        bizLeaveMapper.updateBizLeave(entity);

        // 下一节点处理人待办事项
        bizTodoItemService.insertTodoItem(processInstanceId, entity, "leave");

        return processInstance;
    }

    /**
     * 查询待办任务
     */
    @Transactional(readOnly = true)
    public List<BizLeaveVo> findTodoTasks(HttpServletRequest request, String userId) {
        List<BizLeaveVo> results = new ArrayList();
        List<Task> tasks = new ArrayList<Task>();

        // 根据当前人的ID查询
        List<Task> todoList = taskService.createTaskQuery().processDefinitionKey("leave").taskAssignee(userId).list();

        // 根据当前人未签收的任务
        List<Task> unsignedTasks = taskService.createTaskQuery().processDefinitionKey("leave").taskCandidateUser(userId).list();

        // 合并
        tasks.addAll(todoList);
        tasks.addAll(unsignedTasks);

        // 根据流程的业务ID查询实体并关联
        for (Task task : tasks) {
            String processInstanceId = task.getProcessInstanceId();

            // 条件过滤 1
            if (SQL.isNotNull(request.getParameter("instance_id")) && !request.getParameter("instance_id").equals(processInstanceId)) {
                continue;
            }

            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            String businessKey = processInstance.getBusinessKey();
            BizLeaveVo leave2 = bizLeaveMapper.selectBizLeaveById(new Long(businessKey));

            // 条件过滤 2
            if (SQL.isNotNull(request.getParameter("type")) && !request.getParameter("type").equals(leave2.getType())) {
                continue;
            }

            leave2.setTaskId(task.getId());
            leave2.setTaskName(task.getName());

            SQLList<SQLMap> sysUser = userMapper.getuser(leave2.getApplyUser());
			if (sysUser.size()>0) {
	            leave2.setApplyUserName(sysUser.get(0).getString("contact_name"));
			}

            results.add(leave2);
        }
        return results;
    }

    /**
     * 完成任务
     * @param leave
     * @param saveEntity
     * @param taskId
     * @param variables
     */
    
    public void complete(BizLeaveVo leave, Boolean saveEntity, String taskId, Map<String, Object> variables) {
        if (saveEntity) {
            bizLeaveMapper.updateBizLeave(leave);
        }
        // 只有签收任务，act_hi_taskinst 表的 assignee 字段才不为 null
        taskService.claim(taskId, getUser().getUsername());
        taskService.complete(taskId, variables);

        // 更新待办事项状态
        BizTodoItem query = new BizTodoItem();
        query.setTaskId(taskId);
        // 考虑到候选用户组，会有多个 todoitem 办理同个 task
        List<BizTodoItem> updateList = CollectionUtils.isEmpty(bizTodoItemService.selectBizTodoItemList(query)) ? null : bizTodoItemService.selectBizTodoItemList(query);
        for (BizTodoItem update: updateList) {
            // 找到当前登录用户的 todoitem，置为已办
            if (update.getTodoUserId().equals(getUser().getUsername())) {
                update.setIsView("1");
                update.setIsHandle("1");
                update.setHandleUserId(getUser().getUsername());
                update.setHandleUserName(getUser().getUsername());
                update.setHandleTime(new Date());
                bizTodoItemService.updateBizTodoItem(update);
            } else {
                bizTodoItemService.deleteBizTodoItemById(update.getId()); // 删除候选用户组其他 todoitem
            }
        }

        // 下一节点处理人待办事项
        bizTodoItemService.insertTodoItem(leave.getInstanceId(), leave, "leave");
    }

    /**
     * 查询已办列表
     * @param bizLeave
     * @param userId
     * @return
     */
    
    public List<BizLeaveVo> findDoneTasks(PagedListInfo pagedListInfo, String userId) {
        List<BizLeaveVo> results = new ArrayList();
        HistoricTaskInstanceQuery elist = historyService.createHistoricTaskInstanceQuery()
                .processDefinitionKey("leave")
                .taskAssignee(userId)
                .finished()
                .orderByHistoricTaskInstanceEndTime()
                .desc();
		int count=(int)elist.count();
		pagedListInfo.setMaxRecords(count);
		List<HistoricTaskInstance> list =elist.listPage(pagedListInfo.getCurrentOffset(),pagedListInfo.getCurrentOffset()+pagedListInfo.getItemsPerPage());
        // 根据流程的业务ID查询实体并关联
        for (HistoricTaskInstance instance : list) {
            String processInstanceId = instance.getProcessInstanceId();

            // 条件过滤 1
            if (SQL.isNotNull(pagedListInfo.getMap().get("instance_id")) && !pagedListInfo.getMap().get("instance_id").equals(processInstanceId)) {
                continue;
            }

            HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();

            String businessKey = processInstance.getBusinessKey();
            BizLeaveVo leave2 = bizLeaveMapper.selectBizLeaveById(new Long(businessKey));

            // 条件过滤 2
            if (SQL.isNotNull(pagedListInfo.getMap().get("type")) && !pagedListInfo.getMap().get("type").equals(leave2.getType())) {
                continue;
            }

            leave2.setTaskId(instance.getId());
            leave2.setTaskName(instance.getName());
            leave2.setDoneTime(instance.getEndTime());


			SQLList<SQLMap> sysUser = userMapper.getuser(leave2.getApplyUser());
			if (sysUser.size()>0) {
	            leave2.setApplyUserName(sysUser.get(0).getString("contact_name"));
			}

            results.add(leave2);
        }
        return results;
    }
	public UserDetails getUser(){
		return MSecurityUtils.getUserEntity();
	}
}
